package d0820_Contains;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Program: thread
 * @Description:
 * @Author: Mr.Yiu
 * @CreatedTime: 2021-08-20 11:43
 **/
public class MyContains<T> {
    private final LinkedList<T> list = new LinkedList<T>();
    private final int MAX = 10;
    private int count = 0;

    private Lock lock = new ReentrantLock();
    private Condition producter = lock.newCondition();
    private Condition consumer = lock.newCondition();


    public  void put(T t){
        try {
            lock.lock();
            while (list.size()==MAX){
                 producter.await();
            }
            list.add(t);
            ++count;
            consumer.signalAll();//通知消费者来消费
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public  T get(){
        T t = null;

        try {
            lock.lock();
            while (list.size()==0){
                consumer.await();
            }
            t = list.removeFirst();
            count--;
            producter.signalAll();//通知生产者进行生产

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return t;
    }

    public static void main(String[] args) {
        MyContains<String> c = new MyContains<String>();

        for (int i = 0; i <10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 5; j++) {
                    System.out.println(c.get());
                }
            }, "c" +i).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                for (int j = 0; j < 25; j++) {
                    c.put(Thread.currentThread().getName()+ " " + j);
                }
            },"p"+i).start();
        }
    }

}
